﻿using System;
using System.IO;
using System.Linq;
using Kotonoha.Server.Core.Utils;
using NHibernate;
using NHibernate.Criterion;

namespace Kotonoha.Server.Objects.Model.Event {
    public class MarkEvent : Event {

        public long WordId { get; set; }
        public int Mark { get; set; }

        protected override void serializeInner(TextWriter writer) {
            writer.Write(WordId);
            writer.Write(";");
            writer.Write(Mark);
        }

        protected override void deserializeInner(TextReader reader) {
            string line = reader.ReadLine();
            string[] split = line.Split(';');
            WordId = long.Parse(split[0]);
            Mark = int.Parse(split[1]);
        }

        public bool Equals(MarkEvent obj) {
            if (ReferenceEquals(null, obj)) {
                return false;
            }
            if (ReferenceEquals(this, obj)) {
                return true;
            }
            return base.Equals(obj) && obj.WordId == WordId && obj.Mark == Mark;
        }

        public override bool Equals(object obj) {
            if (ReferenceEquals(null, obj)) {
                return false;
            }
            if (ReferenceEquals(this, obj)) {
                return true;
            }
            return Equals(obj as MarkEvent);
        }

        public override int GetHashCode() {
            unchecked {
                int result = base.GetHashCode();
                result = (result * 397) ^ WordId.GetHashCode();
                result = (result * 397) ^ Mark;
                return result;
            }
        }

        public override void apply(Word word) {
            const string key = "view count";
            int cnt = word.getAdditionalInt(key, 0);

            string markCntKey = string.Format("cnt{0}", Mark);
            int markCnt = word.getAdditionalInt(markCntKey, 0);

            ++markCnt;
            word.Additional[markCntKey] = markCnt.ToString();

            ++cnt;

            word.Additional[key] = cnt.ToString();

            double addVal = Math.Max(0.1, word.Repetition.GetValue(Time) * Math.Pow(5, Mark) * Math.Log(cnt, 1.5) * Math.Pow(Mark + 1, markCnt));
            word.Repetition.Add(addVal, Time);
        }

        public override void apply() {
            ISession session = HibernateUtil.Instance.Session;
            ICriteria criteria = session.CreateCriteria(typeof(Word));
            criteria.Add(Restrictions.Eq("Id", WordId));
            Word w = criteria.UniqueResult<Word>();
            apply(w);
            session.Update(w);
        }
    }
}
